package timeline

import (
	"gitee.com/mootok/mootok/src/constant/strings"
	"gitee.com/mootok/mootok/src/services/feed"
	"gitee.com/mootok/mootok/src/services/timeline"
	"gitee.com/mootok/mootok/src/services/video"
	"gitee.com/mootok/mootok/src/utils/logging"
	"gitee.com/mootok/mootok/src/web/api"
	"gitee.com/mootok/mootok/src/web/common/response"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"net/http"
	"time"
)

type ApiTimelineImpl struct {
}

var VideoService video.Service
var FeedService feed.Service
var Service timeline.Service

const FetchAmount = 20
func (*ApiTimelineImpl) FetchTimeline(c *gin.Context, params api.FetchTimelineParams) {
	var videoIds []int
	var err error
	var cursor int

	categoryId := 1
	if params.Category != nil {
		categoryId = *params.Category
	}
	if params.Cursor == nil {
		cursor = 0
	}  else {
		cursor = *params.Cursor
	}

	logger := logging.LogService("Timeline.Fetch").WithFields(logrus.Fields{
		"categoryId":  categoryId,
		"cursor": cursor,
	})

	userIdAny, _ := c.Get(strings.UserLoginContext)
	userId := userIdAny.(int)

	if categoryId == strings.CategoryHot {
		videoIds, err = Service.GetHotVideos(FetchAmount, 30 * 24 * time.Hour)
		if err != nil {
			logger.Errorf("retrieve videos failed:%v", err)
			response.FailWithMsg(c, http.StatusInternalServerError, strings.DataBaseSelectErrorCode, strings.InternalServiceError)
			return
		}
	} else if categoryId == strings.CategoryFeed {
		videoIds, err = FeedService.GetFollowVideoFeed(c, userId, FetchAmount)
		if err != nil {
			logger.Errorf("retrieve videos failed:%v", err)
			response.FailWithMsg(c, http.StatusInternalServerError, strings.DataBaseSelectErrorCode, strings.InternalServiceError)
			return
		}
	} else if categoryId == strings.CategoryRecommendation {
		videoIds, err = Service.GetRecommendVideos(c, FetchAmount, userId)
		if err != nil {
			logger.Errorf("retrieve videos failed:%v", err)
			response.FailWithMsg(c, http.StatusInternalServerError, strings.DataBaseSelectErrorCode, strings.InternalServiceError)
			return
		}
	} else {
		videoIds, err = Service.GetByCategory(FetchAmount, categoryId, cursor)
		if err != nil {
			logger.Errorf("retrieve videos failed:%v", err)
			response.FailWithMsg(c, http.StatusInternalServerError, strings.DataBaseSelectErrorCode, strings.InternalServiceError)
			return
		}
	}
	if videoIds == nil {
		videoIds, err = Service.GetRandomVideos(FetchAmount)
		if err != nil {
			logger.Errorf("retrieve random videos failed:%v", err)
			response.FailWithMsg(c, http.StatusInternalServerError, strings.DataBaseSelectErrorCode, strings.InternalServiceError)
			return
		}
	}
	videoInfos := make([]api.VideoInfo, len(videoIds))

	if err := VideoService.ToVideoInfoById(videoIds, &userId, &videoInfos); err != nil {
		logger.Errorf("retrieve video info failed:%v", err)
		response.FailWithMsg(c, http.StatusInternalServerError, strings.DataBaseSelectErrorCode, strings.InternalServiceError)
		return
	}

	response.SuccessWithDetail(c, strings.SuccessCode, strings.Success, videoInfos)
	logger.Errorf("success")
}
